//
// File: RFNNpro_v.cpp
//
// MATLAB Coder version            : 5.4
// C/C++ source code generated on  : 20-Jun-2024 17:16:34
//

// Include Files
#include "RFNNpro_v.h"
#include <cmath>

// Function Definitions
//
// Arguments    : const double S[4]
//                const double W[32]
//                double Outputs[2]
//                double Fnk[16]
// Return Type  : void
//
void RFNNpro_v(const double S[4], const double W[32], double Outputs[2],
               double Fnk[16])
{
  static const double c[8]{0.0,
                           10.0,
                           0.0,
                           4.0,
                           -1.5707963267948966,
                           1.5707963267948966,
                           -1.5707963267948966,
                           1.5707963267948966};
  static const double b_dv[4]{4.1, 1.32, 1.0, 1.0};
  double MFs[8];
  double b_a;
  double d;
  int o;
  //  参数初始化
  //  输入层节点数
  //  每个输入的隶属度函数数
  //  模糊规则数
  //  输出层节点数
  //  初始化静态变量
  // 训练均值和标准差
  // VL,VR
  //  隶属度层
  for (int i{0}; i < 4; i++) {
    double c_a;
    b_a = b_dv[i];
    //  定义高斯隶属度函数的参数
    // 均值
    // v标准差
    o = i << 1;
    d = S[i];
    c_a = d - c[o];
    b_a *= b_a;
    MFs[o] = std::exp(-(c_a * c_a) / b_a);
    //  定义高斯隶属度函数的参数
    // 均值
    // v标准差
    c_a = d - c[o + 1];
    MFs[o + 1] = std::exp(-(c_a * c_a) / b_a);
  }
  //  模糊规则层
  for (int i{0}; i < 16; i++) {
    Fnk[i] = 1.0;
    //  计算每条规则的激活程度（AND操作）
    switch (i + 1) {
    case 1:
      b_a = MFs[0];
      if (MFs[0] > MFs[2]) {
        b_a = MFs[2];
      }
      if (b_a > MFs[4]) {
        b_a = MFs[4];
      }
      if (b_a > MFs[6]) {
        b_a = MFs[6];
      }
      Fnk[i] = b_a;
      // near near right right
      break;
    case 2:
      b_a = MFs[0];
      if (MFs[0] > MFs[2]) {
        b_a = MFs[2];
      }
      if (b_a > MFs[4]) {
        b_a = MFs[4];
      }
      if (b_a > MFs[7]) {
        b_a = MFs[7];
      }
      Fnk[i] = b_a;
      // near near right left
      break;
    case 3:
      b_a = MFs[0];
      if (MFs[0] > MFs[2]) {
        b_a = MFs[2];
      }
      if (b_a > MFs[5]) {
        b_a = MFs[5];
      }
      if (b_a > MFs[6]) {
        b_a = MFs[6];
      }
      Fnk[i] = b_a;
      // near near left right
      break;
    case 4:
      b_a = MFs[0];
      if (MFs[0] > MFs[2]) {
        b_a = MFs[2];
      }
      if (b_a > MFs[5]) {
        b_a = MFs[5];
      }
      if (b_a > MFs[7]) {
        b_a = MFs[7];
      }
      Fnk[i] = b_a;
      // near near left left
      break;
    case 5:
      b_a = MFs[0];
      if (MFs[0] > MFs[3]) {
        b_a = MFs[3];
      }
      if (b_a > MFs[4]) {
        b_a = MFs[4];
      }
      if (b_a > MFs[6]) {
        b_a = MFs[6];
      }
      Fnk[i] = b_a;
      // near far right right
      break;
    case 6:
      b_a = MFs[0];
      if (MFs[0] > MFs[3]) {
        b_a = MFs[3];
      }
      if (b_a > MFs[4]) {
        b_a = MFs[4];
      }
      if (b_a > MFs[7]) {
        b_a = MFs[7];
      }
      Fnk[i] = b_a;
      // near far right left
      break;
    case 7:
      b_a = MFs[0];
      if (MFs[0] > MFs[3]) {
        b_a = MFs[3];
      }
      if (b_a > MFs[5]) {
        b_a = MFs[5];
      }
      if (b_a > MFs[6]) {
        b_a = MFs[6];
      }
      Fnk[i] = b_a;
      // near far left right
      break;
    case 8:
      b_a = MFs[0];
      if (MFs[0] > MFs[3]) {
        b_a = MFs[3];
      }
      if (b_a > MFs[5]) {
        b_a = MFs[5];
      }
      if (b_a > MFs[7]) {
        b_a = MFs[7];
      }
      Fnk[i] = b_a;
      // near far left left
      break;
    case 9:
      b_a = MFs[1];
      if (MFs[1] > MFs[2]) {
        b_a = MFs[2];
      }
      if (b_a > MFs[4]) {
        b_a = MFs[4];
      }
      if (b_a > MFs[6]) {
        b_a = MFs[6];
      }
      Fnk[i] = b_a;
      // far near right right
      break;
    case 10:
      b_a = MFs[1];
      if (MFs[1] > MFs[2]) {
        b_a = MFs[2];
      }
      if (b_a > MFs[4]) {
        b_a = MFs[4];
      }
      if (b_a > MFs[7]) {
        b_a = MFs[7];
      }
      Fnk[i] = b_a;
      // far near right left
      break;
    case 11:
      b_a = MFs[1];
      if (MFs[1] > MFs[2]) {
        b_a = MFs[2];
      }
      if (b_a > MFs[5]) {
        b_a = MFs[5];
      }
      if (b_a > MFs[6]) {
        b_a = MFs[6];
      }
      Fnk[i] = b_a;
      // far near left right
      break;
    case 12:
      b_a = MFs[1];
      if (MFs[1] > MFs[2]) {
        b_a = MFs[2];
      }
      if (b_a > MFs[5]) {
        b_a = MFs[5];
      }
      if (b_a > MFs[7]) {
        b_a = MFs[7];
      }
      Fnk[i] = b_a;
      // far near left left
      break;
    case 13:
      b_a = MFs[1];
      if (MFs[1] > MFs[3]) {
        b_a = MFs[3];
      }
      if (b_a > MFs[4]) {
        b_a = MFs[4];
      }
      if (b_a > MFs[6]) {
        b_a = MFs[6];
      }
      Fnk[i] = b_a;
      // far far right right
      break;
    case 14:
      b_a = MFs[1];
      if (MFs[1] > MFs[3]) {
        b_a = MFs[3];
      }
      if (b_a > MFs[4]) {
        b_a = MFs[4];
      }
      if (b_a > MFs[7]) {
        b_a = MFs[7];
      }
      Fnk[i] = b_a;
      // far far right left
      break;
    case 15:
      b_a = MFs[1];
      if (MFs[1] > MFs[3]) {
        b_a = MFs[3];
      }
      if (b_a > MFs[5]) {
        b_a = MFs[5];
      }
      if (b_a > MFs[6]) {
        b_a = MFs[6];
      }
      Fnk[i] = b_a;
      // far far left right
      break;
    default:
      b_a = MFs[1];
      if (MFs[1] > MFs[3]) {
        b_a = MFs[3];
      }
      if (b_a > MFs[5]) {
        b_a = MFs[5];
      }
      if (b_a > MFs[7]) {
        b_a = MFs[7];
      }
      Fnk[i] = b_a;
      // far far left left
      break;
    }
  }
  // 后件层
  //      [rulesOn,i]=max(now_firingStrengths);
  //      Outputs=rulesOn*W(:,i);
  for (o = 0; o < 2; o++) {
    d = 0.0;
    for (int i{0}; i < 16; i++) {
      //  线性组合
      d += Fnk[i] * W[o + (i << 1)];
    }
    Outputs[o] = d;
  }
}

//
// File trailer for RFNNpro_v.cpp
//
// [EOF]
//
